import memoizeOne from 'memoize-one'
import isEqual from 'lodash/isEqual'
import Cookies from 'universal-cookie'
import { routerRedux } from 'dva/router'
import { getUserMenu, getUserInfo } from '@/services/api'

const cookies = new Cookies()

/**
 * get SubMenu or Item
 */
const getSubMenu = item => {
  // doc: add hideChildrenInMenu
  if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
    return {
      ...item,
      children: filterMenuData(item.children), // eslint-disable-line
    }
  }
  return item
}

/**
 * filter menuData
 */
const filterMenuData = menuData => {
  if (!menuData) {
    return []
  }
  return menuData
    .filter(item => item.name && !item.hideInMenu)
    .map(item => getSubMenu(item))
    .filter(item => item)
}
/**
 * 获取面包屑映射
 * @param {Object} menuData 菜单配置
 */
const getBreadcrumbNameMap = menuData => {
  if (!menuData) {
    return {}
  }
  const routerMap = {}

  const flattenMenuData = data => {
    data.forEach(menuItem => {
      if (menuItem.children) {
        flattenMenuData(menuItem.children)
      }
      routerMap[menuItem.path] = menuItem
    })
  }
  flattenMenuData(menuData)
  return routerMap
}

const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual)

function findMenu(path, data) {
  // eslint-disable-next-line no-restricted-syntax
  for (const item of data) {
    if (item.path === path) {
      return item
    }
    if (item.children) {
      const getOne = findMenu(path, item.children)
      if (getOne) return getOne
    }
  }
}

export default {
  namespace: 'menu',

  state: {
    menuData: [],
    routerData: [],
    breadcrumbNameMap: {},
  },

  effects: {
    // 向cookie写入jwtuser数据
    *loadLoinInfo({ payload }, { call }) {
      const response = yield call(getUserInfo, payload)
      const EXT_KEY = 'eva_ext'
      cookies.set(EXT_KEY, response.data || {}, { path: '/' })
    },
    // 加载菜单
    *loadMenuData({ payload }, { call, put, select }) {
      const { location } = payload
      const response = yield call(getUserMenu, payload)
      const menuData = response.data.modules
      const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData)
      yield put({
        type: 'save',
        payload: { menuData, breadcrumbNameMap },
      })
      // 更新currentUser
      yield put({
        type: 'user/saveCurrentUser',
        payload: response.data,
      })

      // const userMenuData = yield select(state => state.menu.menuData)

      // const { pathname } = location

      // if (pathname === '/' || pathname === '/eam' || pathname === '/eam/..') {
      //   yield put(
      //     routerRedux.push({
      //       pathname: userMenuData[0].children[0].path,
      //     }),
      //   )
      // }
    },

    *jumpLink(_, { put, take, select }) {
      let menuData = yield select(state => state.menu.menuData)
      if (menuData.length === 0) {
        yield take('save')
        menuData = yield select(state => state.menu.menuData)
      }
      yield put(
        routerRedux.push({
          pathname: menuData[0].children[0].path,
        }),
      )
    },

    *authRoute({ payload }, { put, take, select }) {
      let menuData = yield select(state => state.menu.menuData)
      if (menuData.length === 0) {
        yield take('save')
        menuData = yield select(state => state.menu.menuData)
      }

      // 存在此menu
      if (!findMenu(payload, [...menuData, { path: '/404' }, { path: '/login' }, { path: '/' }])) {
        console.log('user hasn`t this route', payload)
        yield put(
          routerRedux.push({
            pathname: '/404',
          }),
        )
      }
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        ...action.payload,
      }
    },
  },

  subscriptions: {
    setup({ history, dispatch }) {
      // Subscribe history(url) change, trigger `load` action if pathname is `/`
      history.listen(({ pathname }) => {
        dispatch({
          type: 'authRoute',
          payload: pathname,
        })
      })
    },
  },
}
